package com.miao.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.miao.dto.UserDTO;
import com.miao.entity.User;
import com.miao.entity.UserInfo;
import com.miao.enums.REnum;
import com.miao.exception.BusinessException;
import com.miao.mapper.UserInfoMapper;
import com.miao.mapper.UserMapper;
import com.miao.service.IUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.miao.util.MD5Util;
import com.miao.util.RSAUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.security.interfaces.RSAPrivateKey;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;

/**
 * <p>
 * 用户表 服务实现类
 * </p>
 *
 * @author miao
 * @since 2025-06-03
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
    @Autowired
    private UserMapper userMapper;

    @Autowired
    private UserInfoMapper userInfoMapper;

    @Override
    public void regit(UserDTO userDTO) throws Exception{
        //1、校验手机号是否为空(字符串是否为空使用lang3包) ""
        if (StringUtils.isEmpty(userDTO.getPhone())) {
            throw new BusinessException(REnum.PHONE_IS_NULL.getCode(), REnum.PHONE_IS_NULL.getMsg());
        }

        //2、校验手机号是否已经注册过     使用当前手机号进行数据库查询
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("phone", userDTO.getPhone());

        User user = userMapper.selectOne(queryWrapper);
        if (user != null) {
            throw new BusinessException(REnum.USER_REGISTED.getCode(), REnum.USER_REGISTED.getMsg());
        }

        //3、使用私钥进行解密密码(前端已经使用公钥进行加密，此处用私钥进行解密)
        String decryptPassword = RSAUtil.decrypt(userDTO.getPassword());

        //4、用md5进行密码加密，使用盐值进行加密，降低被破解的概率
        String salt = new Date().getTime() + "";
        String md5EncodePassword = MD5Util.sign(decryptPassword, salt, "utf-8");

        //5、注册（添加user）
        User userRegist = new User();
        userRegist.setPhone(userDTO.getPhone());
        userRegist.setPassword(md5EncodePassword);
        userRegist.setSalt(salt);
        userRegist.setCreateTime(LocalDateTime.now());
        userMapper.insert(userRegist);

        System.out.println(userRegist.getId());

        //6、userInfo也加一条数据
        UserInfo userInfo = new UserInfo();
        userInfo.setUserId(userRegist.getId());
        userInfo.setNick(userDTO.getNick());
        //将INstans转换成localDataTime
        if (userDTO.getBirth() != null) {
            userInfo.setBirth(userDTO.getBirth().atZone(ZoneId.systemDefault()).toLocalDateTime());
        }

         userInfo.setGender(userDTO.getGender());
        userInfo.setCreateTime(LocalDateTime.now());
        userInfoMapper.insert(userInfo);
    }

    @Override
    public String login(UserDTO userDTO) {
        String phone = userDTO.getPhone();
        if (StringUtils.isEmpty(phone)) {
            throw new BusinessException(REnum.PHONE_IS_NULL.getCode(), REnum.PHONE_IS_NULL.getMsg());
        }

        User dbUser = userMapper.selectOne(new QueryWrapper<User>().eq("phone", phone));
        if (dbUser == null) {
            throw new BusinessException(REnum.USER_NOT_EXIST.getCode(), REnum.USER_NOT_EXIST.getMsg());
        }
        if (StringUtils.isEmpty(userDTO.getPassword())) {
            throw new BusinessException(REnum.USER_PASSWORD_NOT_NULL.getCode(), REnum.USER_PASSWORD_NOT_NULL.getMsg());
        }

        String password = userDTO.getPassword();
        String decodeUserPassword;
        try {
            decodeUserPassword = RSAUtil.decrypt(password);
        } catch (Exception e) {
            throw new BusinessException(REnum.PASSWORD_DECODE_ERROR.getCode(), REnum.PASSWORD_DECODE_ERROR.getMsg());
        }

        String md5Password = MD5Util.sign(decodeUserPassword, dbUser.getSalt(), "UTF-8");
        if (!dbUser.getPassword().equals(md5Password)) {
            throw new BusinessException(REnum.USER_PASSWORD_ERROR.getCode(), REnum.USER_PASSWORD_ERROR.getMsg());
        }
//        TokenUtil tokenUtil = new TokenUtil();
        return "token";
    }
}
